<!DOCTYPE html>
<html lang="zh-cn">
    <head><meta charset='utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'><meta name='description' content='用来记录SpringMVC的学习心得'><title>SpringMVC学习笔记</title>

<link rel='canonical' href='https://luobo.cf/p/springmvc/'>

<link rel="stylesheet" href="/scss/style.min.css"><meta property='og:title' content='SpringMVC学习笔记'>
<meta property='og:description' content='用来记录SpringMVC的学习心得'>
<meta property='og:url' content='https://luobo.cf/p/springmvc/'>
<meta property='og:site_name' content='luoboQAQ'>
<meta property='og:type' content='article'><meta property='article:section' content='Post' /><meta property='article:tag' content='Java' /><meta property='article:tag' content='Spring' /><meta property='article:tag' content='笔记' /><meta property='article:published_time' content='2021-08-15T09:06:00&#43;08:00'/><meta property='article:modified_time' content='2021-08-18T16:00:00&#43;08:00'/><meta property='og:image' content='https://luobo.cf/p/springmvc/65411813.jpg' />
<meta name="twitter:title" content="SpringMVC学习笔记">
<meta name="twitter:description" content="用来记录SpringMVC的学习心得"><meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:image" content='https://luobo.cf/p/springmvc/65411813.jpg' />
    </head>
    <body class="
    article-page has-toc
">
    <script>
        (function() {
            const colorSchemeKey = 'StackColorScheme';
            if(!localStorage.getItem(colorSchemeKey)){
                localStorage.setItem(colorSchemeKey, "auto");
            }
        })();
    </script><script>
    (function() {
        const colorSchemeKey = 'StackColorScheme';
        const colorSchemeItem = localStorage.getItem(colorSchemeKey);
        const supportDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches === true;

        if (colorSchemeItem == 'dark' || colorSchemeItem === 'auto' && supportDarkMode) {
            

            document.documentElement.dataset.scheme = 'dark';
        } else {
            document.documentElement.dataset.scheme = 'light';
        }
    })();
</script>
<div class="container main-container flex 
    
        extended
    
">
    
        <div id="article-toolbar">
            <a href="https://luobo.cf" class="back-home">
                <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-chevron-left" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <polyline points="15 6 9 12 15 18" />
</svg>



                <span>返回</span>
            </a>
        </div>
    
<main class="main full-width">
    <article class="has-image main-article">
    <header class="article-header">
        <div class="article-image">
            <a href="/p/springmvc/">
                <img src="/p/springmvc/65411813_hu5438825b9b6d1014226d20d231e650c2_327102_800x0_resize_q75_box.jpg"
                        srcset="/p/springmvc/65411813_hu5438825b9b6d1014226d20d231e650c2_327102_800x0_resize_q75_box.jpg 800w, /p/springmvc/65411813_hu5438825b9b6d1014226d20d231e650c2_327102_1600x0_resize_q75_box.jpg 1600w"
                        width="800" 
                        height="398" 
                        loading="lazy"
                        alt="Featured image of post SpringMVC学习笔记" />
                
            </a>
        </div>
    

    <div class="article-details">
    

    <h2 class="article-title">
        <a href="/p/springmvc/">SpringMVC学习笔记</a>
    </h2>

    
    <h3 class="article-subtitle">
        用来记录SpringMVC的学习心得
    </h3>
    

    
    <footer class="article-time">
        
            <div>
                <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-calendar-time" width="56" height="56" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <path d="M11.795 21h-6.795a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v4" />
  <circle cx="18" cy="18" r="4" />
  <path d="M15 3v4" />
  <path d="M7 3v4" />
  <path d="M3 11h16" />
  <path d="M18 16.496v1.504l1 1" />
</svg>
                <time class="article-time--published">Aug 15, 2021</time>
            </div>
        

        
            <div>
                <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-clock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="12" cy="12" r="9" />
  <polyline points="12 7 12 12 15 15" />
</svg>



                <time class="article-time--reading">
                    阅读时长: 7 分钟
                </time>
            </div>
        
    </footer>
    
</div>
</header>

    <section class="article-content">
    <p>SpringMVC也告一段落了，终于要到SpringBoot了。</p>
<p>还是和之前一样，笔记是基于<a class="link" href="https://space.bilibili.com/95256449"  target="_blank" rel="noopener"
    >遇见狂神说</a>的<a class="link" href="https://www.bilibili.com/video/BV1aE41167Tu"  target="_blank" rel="noopener"
    >SpringMVC视频教程</a>而来，在此感谢能提供这么优秀的教程。</p>
<h2 id="回顾mvc">回顾MVC</h2>
<h3 id="什么是mvc">什么是MVC</h3>
<ul>
<li>MVC是模型(Model)、视图(View)、控制器(Controller)的简写，是一种软件设计规范。</li>
<li>将业务逻辑、数据、显示分离的方法来组织代码。</li>
</ul>
<p>**Model（模型）：**数据模型，提供要展示的数据，因此包含数据和行为，可以认为是领域模型或JavaBean组件（包含数据和行为），不过现在一般都分离开来：Value Object（数据Dao） 和 服务层（行为Service）。也就是模型提供了模型数据查询和模型数据的状态更新等功能，包括数据和业务。</p>
<p>拓展：在前端数据传输给后端时，有些字段是不需要的，这是可能会细分出Vo层（视图）</p>
<p>比如：用户有账号、密码、年龄等一系列字段</p>
<p>这时前端登录只传了账号密码</p>
<p>此时可以用UserVo来表示，里面只有账号和密码</p>
<p>**View（视图）：**负责进行模型的展示，一般就是我们见到的用户界面，客户想看到的东西。</p>
<p>**Controller（控制器）：**接收用户请求，委托给模型进行处理（状态改变），处理完毕后把返回的模型数据返回给视图，由视图负责展示。也就是说控制器做了个调度员的工作。</p>
<p><strong>最典型的MVC就是JSP + servlet + javabean的模式。</strong></p>
<ol>
<li>用户发请求</li>
<li>Servlet接收请求数据，并调用对应的业务逻辑方法</li>
<li>业务处理完毕，返回更新后的数据给servlet</li>
<li>servlet转向到JSP，由JSP来渲染页面</li>
<li>响应给前端更新后的页面</li>
</ol>
<p><strong>职责分析：</strong></p>
<p><strong>Controller：控制器</strong></p>
<ol>
<li>取得表单数据</li>
<li>调用业务逻辑</li>
<li>转向指定的页面</li>
</ol>
<p><strong>Model：模型</strong></p>
<ol>
<li>业务逻辑</li>
<li>保存数据的状态</li>
</ol>
<p><strong>View：视图</strong></p>
<ol>
<li>显示页面</li>
</ol>
<h3 id="复习servlet">复习Servlet</h3>
<ol>
<li>
<p>父工程添加依赖</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;dependencies&gt;</span>
    <span class="nt">&lt;dependency&gt;</span>
        <span class="nt">&lt;groupId&gt;</span>junit<span class="nt">&lt;/groupId&gt;</span>
        <span class="nt">&lt;artifactId&gt;</span>junit<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;version&gt;</span>4.13<span class="nt">&lt;/version&gt;</span>
    <span class="nt">&lt;/dependency&gt;</span>
    <span class="nt">&lt;dependency&gt;</span>
        <span class="nt">&lt;groupId&gt;</span>org.springframework<span class="nt">&lt;/groupId&gt;</span>
        <span class="nt">&lt;artifactId&gt;</span>spring-webmvc<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;version&gt;</span>5.3.9<span class="nt">&lt;/version&gt;</span>
    <span class="nt">&lt;/dependency&gt;</span>
    <span class="nt">&lt;dependency&gt;</span>
        <span class="nt">&lt;groupId&gt;</span>javax.servlet<span class="nt">&lt;/groupId&gt;</span>
        <span class="nt">&lt;artifactId&gt;</span>javax.servlet-api<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;version&gt;</span>3.1.0<span class="nt">&lt;/version&gt;</span>
        <span class="nt">&lt;scope&gt;</span>provided<span class="nt">&lt;/scope&gt;</span>
    <span class="nt">&lt;/dependency&gt;</span>
    <span class="nt">&lt;dependency&gt;</span>
        <span class="nt">&lt;groupId&gt;</span>javax.servlet.jsp<span class="nt">&lt;/groupId&gt;</span>
        <span class="nt">&lt;artifactId&gt;</span>jsp-api<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;version&gt;</span>2.2<span class="nt">&lt;/version&gt;</span>
    <span class="nt">&lt;/dependency&gt;</span>
    <span class="nt">&lt;dependency&gt;</span>
        <span class="nt">&lt;groupId&gt;</span>javax.servlet<span class="nt">&lt;/groupId&gt;</span>
        <span class="nt">&lt;artifactId&gt;</span>jstl<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;version&gt;</span>1.2<span class="nt">&lt;/version&gt;</span>
    <span class="nt">&lt;/dependency&gt;</span>
<span class="nt">&lt;/dependencies&gt;</span>
</code></pre></div></li>
<li>
<p>编写Servlet</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">HelloServlet</span> <span class="kd">extends</span> <span class="n">HttpServlet</span> <span class="o">{</span>
    <span class="nd">@Override</span>
    <span class="kd">protected</span> <span class="kt">void</span> <span class="nf">doGet</span><span class="o">(</span><span class="n">HttpServletRequest</span> <span class="n">req</span><span class="o">,</span> <span class="n">HttpServletResponse</span> <span class="n">resp</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">ServletException</span><span class="o">,</span> <span class="n">IOException</span> <span class="o">{</span>
        <span class="c1">//获取前端操作
</span><span class="c1"></span>        <span class="n">String</span> <span class="n">method</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="na">getParameter</span><span class="o">(</span><span class="s">&#34;method&#34;</span><span class="o">);</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">method</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="s">&#34;add&#34;</span><span class="o">)){</span>
            <span class="n">req</span><span class="o">.</span><span class="na">getSession</span><span class="o">().</span><span class="na">setAttribute</span><span class="o">(</span><span class="s">&#34;msg&#34;</span><span class="o">,</span><span class="s">&#34;执行了add方法&#34;</span><span class="o">);</span>
        <span class="o">}</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">method</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="s">&#34;delete&#34;</span><span class="o">)){</span>
            <span class="n">req</span><span class="o">.</span><span class="na">getSession</span><span class="o">().</span><span class="na">setAttribute</span><span class="o">(</span><span class="s">&#34;msg&#34;</span><span class="o">,</span><span class="s">&#34;执行了delete方法&#34;</span><span class="o">);</span>
        <span class="o">}</span>
        <span class="c1">//调用业务层
</span><span class="c1"></span>        <span class="c1">//视图转发或重定向
</span><span class="c1"></span>        <span class="n">req</span><span class="o">.</span><span class="na">getRequestDispatcher</span><span class="o">(</span><span class="s">&#34;/WEB-INF/jsp/test.jsp&#34;</span><span class="o">).</span><span class="na">forward</span><span class="o">(</span><span class="n">req</span><span class="o">,</span><span class="n">resp</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">protected</span> <span class="kt">void</span> <span class="nf">doPost</span><span class="o">(</span><span class="n">HttpServletRequest</span> <span class="n">req</span><span class="o">,</span> <span class="n">HttpServletResponse</span> <span class="n">resp</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">ServletException</span><span class="o">,</span> <span class="n">IOException</span> <span class="o">{</span>
        <span class="n">doGet</span><span class="o">(</span><span class="n">req</span><span class="o">,</span> <span class="n">resp</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></li>
<li>
<p>编写<code>test.jsp</code>，在<code>WEB-INF</code>目录下新建一个<code>jsp</code>的文件夹，新建<code>test.jsp</code></p>
<pre><code class="language-jsp" data-lang="jsp">&lt;%@ page contentType=&quot;text/html;charset=UTF-8&quot; language=&quot;java&quot; %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
${msg}
&lt;/body&gt;
&lt;/html&gt;
</code></pre></li>
<li>
<p>在<code>web.xml</code>中注册Servlet</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;servlet&gt;</span>
    <span class="nt">&lt;servlet-name&gt;</span>hello<span class="nt">&lt;/servlet-name&gt;</span>
    <span class="nt">&lt;servlet-class&gt;</span>top.lbqaq.servlet.HelloServlet<span class="nt">&lt;/servlet-class&gt;</span>
<span class="nt">&lt;/servlet&gt;</span>

<span class="nt">&lt;servlet-mapping&gt;</span>
    <span class="nt">&lt;servlet-name&gt;</span>hello<span class="nt">&lt;/servlet-name&gt;</span>
    <span class="nt">&lt;url-pattern&gt;</span>/hello<span class="nt">&lt;/url-pattern&gt;</span>
<span class="nt">&lt;/servlet-mapping&gt;</span>
</code></pre></div></li>
<li>
<p>配置TomCat，进行测试</p>
</li>
</ol>
<p><strong>MVC框架要做哪些事情</strong></p>
<ol>
<li>将url映射到java类或java类的方法 .</li>
<li>封装用户提交的数据 .</li>
<li>处理请求&ndash;调用相关的业务处理&ndash;封装响应数据 .</li>
<li>将响应的数据进行渲染 . jsp / html 等表示层数据 .</li>
</ol>
<p><strong>说明：</strong></p>
<p>​	常见的服务器端MVC框架有：Struts、Spring MVC、ASP.NET MVC、Zend Framework、JSF；常见前端MVC框架：vue、angularjs、react、backbone；由MVC演化出了另外一些模式如：MVP、MVVM 等等&hellip;.</p>
<h2 id="什么是springmvc">什么是SpringMVC</h2>
<h3 id="概述">概述</h3>
<p>Spring MVC是Spring Framework的一部分，是基于Java实现MVC的轻量级Web框架。</p>
<p><a class="link" href="https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/web.html"  target="_blank" rel="noopener"
    >中文文档</a></p>
<p><strong>我们为什么要学习SpringMVC呢?</strong></p>
<p>Spring MVC的特点：</p>
<ol>
<li>轻量级，简单易学</li>
<li>高效 , 基于请求响应的MVC框架</li>
<li>与Spring兼容性好，无缝结合</li>
<li>约定优于配置</li>
<li>功能强大：RESTful、数据验证、格式化、本地化、主题等</li>
<li>简洁灵活</li>
</ol>
<h3 id="中心控制器">中心控制器</h3>
<p>​	Spring的web框架围绕DispatcherServlet设计。DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始，使用Java 5或者以上版本的用户可以采用基于注解的controller声明方式。</p>
<p>​	Spring MVC框架像许多其他MVC框架一样, <strong>以请求为驱动</strong> , <strong>围绕一个中心Servlet分派请求及提供其他功能</strong>，<strong>DispatcherServlet是一个实际的Servlet (它继承自HttpServlet 基类)</strong>。</p>
<p><figure style="flex-grow: 198; flex-basis: 476px">
		<a href="/p/springmvc/IMAGE/1.webp" data-size="1080x544"><img src="/p/springmvc/IMAGE/1.webp"
				srcset="/p/springmvc/IMAGE/1_hu3ae3d7abd996046a483493c2f9ce3e4d_130291_480x0_resize_q75_h2_box_2.webp 480w, /p/springmvc/IMAGE/1_hu3ae3d7abd996046a483493c2f9ce3e4d_130291_1024x0_resize_q75_h2_box_2.webp 1024w"
				width="1080"
				height="544"
				loading="lazy"
				alt="DispatcherServlet">
		</a>
		
		<figcaption>DispatcherServlet</figcaption>
		
	</figure></p>
<p>SpringMVC的原理如下图所示：</p>
<p>​	当发起请求时被前置的控制器拦截到请求，根据请求参数生成代理请求，找到请求对应的实际控制器，控制器处理请求，创建数据模型，访问数据库，将模型响应给中心控制器，控制器使用模型与视图渲染视图结果，将结果返回给中心控制器，再将结果返回给请求者。</p>
<p><figure style="flex-grow: 203; flex-basis: 488px">
		<a href="/p/springmvc/IMAGE/2.webp" data-size="930x457"><img src="/p/springmvc/IMAGE/2.webp"
				srcset="/p/springmvc/IMAGE/2_hu84e54ca18cc3cb270153e6879a8b884f_168308_480x0_resize_q75_h2_box_2.webp 480w, /p/springmvc/IMAGE/2_hu84e54ca18cc3cb270153e6879a8b884f_168308_1024x0_resize_q75_h2_box_2.webp 1024w"
				width="930"
				height="457"
				loading="lazy"
				alt="SpringMVC流程">
		</a>
		
		<figcaption>SpringMVC流程</figcaption>
		
	</figure></p>
<h3 id="springmvc执行原理">SpringMVC执行原理</h3>
<p><figure style="flex-grow: 187; flex-basis: 450px">
		<a href="/p/springmvc/IMAGE/3.webp" data-size="952x507"><img src="/p/springmvc/IMAGE/3.webp"
				srcset="/p/springmvc/IMAGE/3_hu4c84172d8d8e4cc230c228551308ad18_221329_480x0_resize_q75_h2_box_2.webp 480w, /p/springmvc/IMAGE/3_hu4c84172d8d8e4cc230c228551308ad18_221329_1024x0_resize_q75_h2_box_2.webp 1024w"
				width="952"
				height="507"
				loading="lazy"
				alt="执行流程">
		</a>
		
		<figcaption>执行流程</figcaption>
		
	</figure></p>
<p>图为SpringMVC的一个较完整的流程图，实线表示SpringMVC框架提供的技术，不需要开发者实现，虚线表示需要开发者实现。</p>
<p><strong>简要分析执行流程</strong></p>
<ol>
<li>
<p>DispatcherServlet表示前置控制器，是整个SpringMVC的控制中心。用户发出请求，DispatcherServlet接收请求并拦截请求。</p>
<p>我们假设请求的url为 : <code>http://localhost:8080/SpringMVC/hello</code></p>
<p><strong>如上url拆分成三部分：</strong></p>
<p><code>http://localhost:8080</code>服务器域名</p>
<p>SpringMVC部署在服务器上的web站点</p>
<p>hello表示控制器</p>
<p>通过分析，如上url表示为：请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。</p>
</li>
<li>
<p>HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。</p>
</li>
<li>
<p>HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器，如上url被查找控制器为：hello。</p>
</li>
<li>
<p>HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。</p>
</li>
<li>
<p>HandlerAdapter表示处理器适配器，其按照特定的规则去执行Handler。</p>
</li>
<li>
<p>Handler让具体的Controller执行。</p>
</li>
<li>
<p>Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。</p>
</li>
<li>
<p>HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。</p>
</li>
<li>
<p>DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。</p>
</li>
<li>
<p>视图解析器将解析的逻辑视图名传给DispatcherServlet。</p>
</li>
<li>
<p>DispatcherServlet根据视图解析器解析的视图结果，调用具体的视图。</p>
</li>
<li>
<p>最终视图呈现给用户。</p>
</li>
</ol>
<p>这里比较绕，所以直接把原文搬来了，之后等理解加深了再来补充自己的看法。</p>
<h2 id="第一个springmvc程序">第一个SpringMVC程序</h2>
<p>由于我们是采用子模块的方式，那么需要去IDEA里设置一下让lib会打包出去。否则就会提示404错误。</p>
<p>在点击IDEA右上角的小齿轮，选择<code>项目结构</code>，在<code>工件</code>下看<code>WEB-INF</code>里是否有<code>lib</code>目录，没有的话就创建一个，然后点击<code>+</code>号，选择<code>库文件</code>将所有的包导入进去。</p>
<h4 id="配置版">配置版</h4>
<ol>
<li>
<p>准备要看的视图。在<code>WEB-INF</code>目录下创建<code>jsp</code>目录，在里面创建<code>test.jsp</code>，填入<code>${msg}</code></p>
</li>
<li>
<p>配置SpringMVC。在<code>web.xml</code>里添加下面的代码。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
<span class="nt">&lt;web-app</span> <span class="na">xmlns=</span><span class="s">&#34;http://xmlns.jcp.org/xml/ns/javaee&#34;</span>
         <span class="na">xmlns:xsi=</span><span class="s">&#34;http://www.w3.org/2001/XMLSchema-instance&#34;</span>
         <span class="na">xsi:schemaLocation=</span><span class="s">&#34;http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd&#34;</span>
         <span class="na">version=</span><span class="s">&#34;4.0&#34;</span><span class="nt">&gt;</span>

    <span class="c">&lt;!--配置DispatchServlet：这是SpringMVC的核心：请求分发器、前端控制器--&gt;</span>
    <span class="nt">&lt;servlet&gt;</span>
        <span class="nt">&lt;servlet-name&gt;</span>springmvc<span class="nt">&lt;/servlet-name&gt;</span>
        <span class="nt">&lt;servlet-class&gt;</span>org.springframework.web.servlet.DispatcherServlet<span class="nt">&lt;/servlet-class&gt;</span>
        <span class="c">&lt;!--DispatchServlet要绑定Spring的配置文件--&gt;</span>
        <span class="nt">&lt;init-param&gt;</span>
            <span class="nt">&lt;param-name&gt;</span>contextConfigLocation<span class="nt">&lt;/param-name&gt;</span>
            <span class="nt">&lt;param-value&gt;</span>classpath:springmvc-servlet.xml<span class="nt">&lt;/param-value&gt;</span>
        <span class="nt">&lt;/init-param&gt;</span>
        <span class="c">&lt;!--启动级别1：随服务器一起启动--&gt;</span>
        <span class="nt">&lt;load-on-startup&gt;</span>1<span class="nt">&lt;/load-on-startup&gt;</span>
    <span class="nt">&lt;/servlet&gt;</span>

    <span class="nt">&lt;servlet-mapping&gt;</span>
        <span class="nt">&lt;servlet-name&gt;</span>springmvc<span class="nt">&lt;/servlet-name&gt;</span>
        <span class="nt">&lt;url-pattern&gt;</span>/<span class="nt">&lt;/url-pattern&gt;</span>
    <span class="nt">&lt;/servlet-mapping&gt;</span>
<span class="nt">&lt;/web-app&gt;</span>
</code></pre></div><p><strong>备注：</strong><code>/</code>和<code>/*</code>的区别：<code>/</code>匹配所有请求，不匹配jsp页面；<code>/*</code>会匹配jsp页面，这样会导致嵌套，一般不会用</p>
</li>
<li>
<p>编写SpringMVC的配置文件<code>springmvc-servlet.xml</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
<span class="nt">&lt;beans</span> <span class="na">xmlns=</span><span class="s">&#34;http://www.springframework.org/schema/beans&#34;</span>
       <span class="na">xmlns:xsi=</span><span class="s">&#34;http://www.w3.org/2001/XMLSchema-instance&#34;</span>
       <span class="na">xsi:schemaLocation=</span><span class="s">&#34;http://www.springframework.org/schema/beans
</span><span class="s">       http://www.springframework.org/schema/beans/spring-beans.xsd&#34;</span><span class="nt">&gt;</span>

    <span class="c">&lt;!--处理器映射器--&gt;</span>
    <span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">&#34;org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping&#34;</span><span class="nt">/&gt;</span>
    <span class="c">&lt;!--处理器适配器--&gt;</span>
    <span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">&#34;org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter&#34;</span><span class="nt">/&gt;</span>

    <span class="c">&lt;!--视图解析器--&gt;</span>
    <span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">&#34;org.springframework.web.servlet.view.InternalResourceViewResolver&#34;</span> <span class="na">id=</span><span class="s">&#34;internalResourceViewResolver&#34;</span><span class="nt">&gt;</span>
        <span class="c">&lt;!--前缀--&gt;</span>
        <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&#34;prefix&#34;</span> <span class="na">value=</span><span class="s">&#34;/WEB-INF/jsp/&#34;</span><span class="nt">/&gt;</span>
        <span class="c">&lt;!--后缀--&gt;</span>
        <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&#34;suffix&#34;</span> <span class="na">value=</span><span class="s">&#34;.jsp&#34;</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/bean&gt;</span>
<span class="nt">&lt;/beans&gt;</span>
</code></pre></div></li>
<li>
<p>实现Controller接口</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">top.lbqaq.Controller</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">org.springframework.web.servlet.ModelAndView</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.web.servlet.mvc.Controller</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">javax.servlet.http.HttpServletRequest</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.servlet.http.HttpServletResponse</span><span class="o">;</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">HelloController</span> <span class="kd">implements</span> <span class="n">Controller</span> <span class="o">{</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="n">ModelAndView</span> <span class="nf">handleRequest</span><span class="o">(</span><span class="n">HttpServletRequest</span> <span class="n">httpServletRequest</span><span class="o">,</span> <span class="n">HttpServletResponse</span> <span class="n">httpServletResponse</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
        <span class="n">ModelAndView</span> <span class="n">mv</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ModelAndView</span><span class="o">();</span>
        <span class="c1">//业务代码
</span><span class="c1"></span>        <span class="n">String</span> <span class="n">result</span> <span class="o">=</span> <span class="s">&#34;HelloSpringMVC&#34;</span><span class="o">;</span>
        <span class="n">mv</span><span class="o">.</span><span class="na">addObject</span><span class="o">(</span><span class="s">&#34;msg&#34;</span><span class="o">,</span><span class="n">result</span><span class="o">);</span>
        <span class="c1">//视图跳转
</span><span class="c1"></span>        <span class="n">mv</span><span class="o">.</span><span class="na">setViewName</span><span class="o">(</span><span class="s">&#34;test&#34;</span><span class="o">);</span>
        <span class="k">return</span> <span class="n">mv</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></li>
<li>
<p>将Controller在Spring中注册(<code>springmvc-servlet.xml</code>)</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="c">&lt;!--BeanNameUrlHandlerMapping:按BeanName匹配--&gt;</span>
<span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&#34;/hello&#34;</span> <span class="na">class=</span><span class="s">&#34;top.lbqaq.Controller.HelloController&#34;</span><span class="nt">/&gt;</span>
</code></pre></div></li>
<li>
<p>运行TomCat查看结果</p>
</li>
</ol>
<p>然而正常开发并不会使用这样的方式，这样做只是为了理解底层的操作。_(:з)∠)_</p>
<h4 id="注解版">注解版</h4>
<ol>
<li>
<p>配置<code>Web.xml</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml">    <span class="c">&lt;!--配置DispatchServlet：这是SpringMVC的核心：请求分发器、前端控制器--&gt;</span>
    <span class="nt">&lt;servlet&gt;</span>
        <span class="nt">&lt;servlet-name&gt;</span>springmvc<span class="nt">&lt;/servlet-name&gt;</span>
        <span class="nt">&lt;servlet-class&gt;</span>org.springframework.web.servlet.DispatcherServlet<span class="nt">&lt;/servlet-class&gt;</span>
        <span class="c">&lt;!--DispatchServlet要绑定Spring的配置文件--&gt;</span>
        <span class="nt">&lt;init-param&gt;</span>
            <span class="nt">&lt;param-name&gt;</span>contextConfigLocation<span class="nt">&lt;/param-name&gt;</span>
            <span class="nt">&lt;param-value&gt;</span>classpath:springmvc-servlet.xml<span class="nt">&lt;/param-value&gt;</span>
        <span class="nt">&lt;/init-param&gt;</span>
        <span class="c">&lt;!--启动级别1：随服务器一起启动；越小级别越高--&gt;</span>
        <span class="nt">&lt;load-on-startup&gt;</span>1<span class="nt">&lt;/load-on-startup&gt;</span>
    <span class="nt">&lt;/servlet&gt;</span>

    <span class="nt">&lt;servlet-mapping&gt;</span>
        <span class="nt">&lt;servlet-name&gt;</span>springmvc<span class="nt">&lt;/servlet-name&gt;</span>
        <span class="nt">&lt;url-pattern&gt;</span>/<span class="nt">&lt;/url-pattern&gt;</span>
    <span class="nt">&lt;/servlet-mapping&gt;</span>
</code></pre></div><p>还是老样子，这里没有什么需要改动的。</p>
</li>
<li>
<p>在<code>resources</code>目录下添加SpringMVC配置文件<code>springmvc-servlet.xml</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
<span class="nt">&lt;beans</span> <span class="na">xmlns=</span><span class="s">&#34;http://www.springframework.org/schema/beans&#34;</span>
       <span class="na">xmlns:xsi=</span><span class="s">&#34;http://www.w3.org/2001/XMLSchema-instance&#34;</span>
       <span class="na">xmlns:context=</span><span class="s">&#34;http://www.springframework.org/schema/context&#34;</span>
       <span class="na">xmlns:mvc=</span><span class="s">&#34;http://www.springframework.org/schema/mvc&#34;</span>
       <span class="na">xsi:schemaLocation=</span><span class="s">&#34;http://www.springframework.org/schema/beans
</span><span class="s">       http://www.springframework.org/schema/beans/spring-beans.xsd
</span><span class="s">       http://www.springframework.org/schema/context
</span><span class="s">       https://www.springframework.org/schema/context/spring-context.xsd
</span><span class="s">       http://www.springframework.org/schema/mvc
</span><span class="s">       https://www.springframework.org/schema/mvc/spring-mvc.xsd&#34;</span><span class="nt">&gt;</span>

    <span class="c">&lt;!-- 自动扫描包，让指定包下的注解生效,由IOC容器统一管理 --&gt;</span>
    <span class="nt">&lt;context:component-scan</span> <span class="na">base-package=</span><span class="s">&#34;top.lbqaq.controller&#34;</span><span class="nt">/&gt;</span>
    <span class="c">&lt;!-- 让Spring MVC不处理静态资源 --&gt;</span>
    <span class="nt">&lt;mvc:default-servlet-handler</span> <span class="nt">/&gt;</span>
    <span class="c">&lt;!--
</span><span class="c">    支持mvc注解驱动
</span><span class="c">        在spring中一般采用@RequestMapping注解来完成映射关系
</span><span class="c">        要想使@RequestMapping注解生效
</span><span class="c">        必须向上下文中注册DefaultAnnotationHandlerMapping
</span><span class="c">        和一个AnnotationMethodHandlerAdapter实例
</span><span class="c">        这两个实例分别在类级别和方法级别处理。
</span><span class="c">        而annotation-driven配置帮助我们自动完成上述两个实例的注入。
</span><span class="c">     --&gt;</span>
    <span class="nt">&lt;mvc:annotation-driven</span> <span class="nt">/&gt;</span>

    <span class="c">&lt;!-- 视图解析器 --&gt;</span>
    <span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">&#34;org.springframework.web.servlet.view.InternalResourceViewResolver&#34;</span>
          <span class="na">id=</span><span class="s">&#34;internalResourceViewResolver&#34;</span><span class="nt">&gt;</span>
        <span class="c">&lt;!-- 前缀 --&gt;</span>
        <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&#34;prefix&#34;</span> <span class="na">value=</span><span class="s">&#34;/WEB-INF/jsp/&#34;</span> <span class="nt">/&gt;</span>
        <span class="c">&lt;!-- 后缀 --&gt;</span>
        <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&#34;suffix&#34;</span> <span class="na">value=</span><span class="s">&#34;.jsp&#34;</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;/bean&gt;</span>

<span class="nt">&lt;/beans&gt;</span>
</code></pre></div></li>
<li>
<p>创建Controller</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="nd">@Controller</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">HelloController</span> <span class="o">{</span>
    <span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">&#34;/hello&#34;</span><span class="o">)</span>
    <span class="kd">public</span> <span class="n">String</span> <span class="nf">hello</span><span class="o">(</span><span class="n">Model</span> <span class="n">model</span><span class="o">){</span>
        <span class="c1">//封装数据
</span><span class="c1"></span>        <span class="n">model</span><span class="o">.</span><span class="na">addAttribute</span><span class="o">(</span><span class="s">&#34;msg&#34;</span><span class="o">,</span><span class="s">&#34;Hello,SpringMVCAnnotation!&#34;</span><span class="o">);</span>
        <span class="k">return</span> <span class="s">&#34;hello&#34;</span><span class="o">;</span>  <span class="c1">//会被视图解析器处理
</span><span class="c1"></span>    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><ul>
<li>@Controller是为了让Spring IOC容器初始化时自动扫描到；</li>
<li>@RequestMapping是为了映射请求路径，这里因为类与方法上都有映射所以访问时应该是/hello；</li>
<li>方法中声明Model类型的参数是为了把Action中的数据带到视图中；</li>
<li>方法返回的结果是视图的名称hello，加上配置文件中的前后缀变成WEB-INF/jsp/<strong>hello</strong>.jsp。</li>
</ul>
</li>
<li>
<p>创建视图层，在<code>WEB-INF/jsp</code>目录中创建<code>hello.jsp</code></p>
<pre><code class="language-jsp" data-lang="jsp">&lt;%@ page contentType=&quot;text/html;charset=UTF-8&quot; language=&quot;java&quot; %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
${msg}
&lt;/body&gt;
&lt;/html&gt;
</code></pre></li>
<li>
<p>运行TomCat查看结果</p>
</li>
</ol>
<h4 id="小结">小结</h4>
<p>实现步骤其实非常的简单：</p>
<ol>
<li>新建一个web项目</li>
<li>导入相关jar包</li>
<li>编写web.xml , 注册DispatcherServlet</li>
<li>编写springmvc配置文件</li>
<li>接下来就是去创建对应的控制类 , controller</li>
<li>最后完善前端视图和controller之间的对应</li>
<li>测试运行调试.</li>
</ol>
<p>使用springMVC必须配置的三大件：</p>
<p><strong>处理器映射器、处理器适配器、视图解析器</strong></p>
<p>通常，我们只需要<strong>手动配置视图解析器</strong>，而<strong>处理器映射器</strong>和<strong>处理器适配器</strong>只需要开启<strong>注解驱动</strong>即可，而省去了大段的xml配置</p>
<h2 id="restful风格">RestFul风格</h2>
<p><strong>概念</strong></p>
<p>Restful就是一个资源定位及资源操作的风格。不是标准也不是协议，只是一种风格。基于这个风格设计的软件可以更简洁，更有层次，更易于实现缓存等机制。</p>
<p><strong>功能</strong></p>
<p>资源：互联网所有的事物都可以被抽象为资源</p>
<p>资源操作：使用POST、DELETE、PUT、GET，使用不同方法对资源进行操作。</p>
<p>分别对应 添加、 删除、修改、查询。</p>
<p><strong>传统方式操作资源</strong>  ：通过不同的参数来实现不同的效果！方法单一，post 和 get</p>
<p>​	http://127.0.0.1/item/queryItem.action?id=1 查询,GET</p>
<p>​	http://127.0.0.1/item/saveItem.action 新增,POST</p>
<p>​	http://127.0.0.1/item/updateItem.action 更新,POST</p>
<p>​	http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST</p>
<p><strong>使用RESTful操作资源</strong> ：可以通过不同的请求方式来实现不同的效果！如下：请求地址一样，但是功能可以不同！</p>
<p>​	http://127.0.0.1/item/1 查询,GET</p>
<p>​	http://127.0.0.1/item 新增,POST</p>
<p>​	http://127.0.0.1/item 更新,PUT</p>
<p>​	http://127.0.0.1/item/1 删除,DELETE</p>
<p><strong>使用方法</strong></p>
<p>创建一个类<code>RestFulController</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="nd">@Controller</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">RestFulController</span> <span class="o">{</span>

    <span class="c1">//原来的：localhost:8085/add?a=1&amp;b=2
</span><span class="c1"></span>    <span class="c1">//Restful:localhost:8085/add/1/2
</span><span class="c1"></span>    <span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">&#34;/add/{a}/{b}&#34;</span><span class="o">)</span>
    <span class="kd">public</span> <span class="n">String</span> <span class="nf">test1</span><span class="o">(</span><span class="nd">@PathVariable</span> <span class="kt">int</span> <span class="n">a</span><span class="o">,</span><span class="nd">@PathVariable</span> <span class="kt">int</span> <span class="n">b</span><span class="o">,</span> <span class="n">Model</span> <span class="n">model</span><span class="o">){</span>
        <span class="kt">int</span> <span class="n">res</span> <span class="o">=</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span><span class="o">;</span>
        <span class="n">model</span><span class="o">.</span><span class="na">addAttribute</span><span class="o">(</span><span class="s">&#34;msg&#34;</span><span class="o">,</span><span class="s">&#34;结果为&#34;</span><span class="o">+</span><span class="n">res</span><span class="o">);</span>
        <span class="k">return</span> <span class="s">&#34;test&#34;</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p><code>@RequestMapping</code>里面的<code>{a}</code>就代表这里是传给a变量的值；下面的a变量前要加<code>@PathVariable</code></p>
<p>使用路径变量的好处？</p>
<ul>
<li>使路径变得更加简洁；</li>
<li>获得参数更加方便，框架会自动进行类型转换。</li>
<li>通过路径变量的类型可以约束访问参数，如果类型不一样，则访问不到对应的请求方法，如这里访问是的路径是/commit/1/a，则路径与方法不匹配，而不会是参数转换失败。</li>
</ul>
<p>我们也可以进行方法约束，让其只响应某一种请求</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="nd">@GetMapping</span>
<span class="nd">@PostMapping</span>
<span class="nd">@PutMapping</span>
<span class="nd">@DeleteMapping</span>
<span class="nd">@PatchMapping</span>
</code></pre></div><p>拿<code>@GetMapping</code>来说，就是<code>@RequestMapping(method =RequestMethod.GET)</code>意思，如果使用其他的方法，将会报405错误。</p>
<h2 id="重定向和转发">重定向和转发</h2>
<p>重定向不需要视图解析器，本质就是重新请求一个新地方。</p>
<p>可以重定向到另外一个请求实现。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="nd">@Controller</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ResultSpringMVC2</span> <span class="o">{</span>
    <span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">&#34;/rsm2/t1&#34;</span><span class="o">)</span>
    <span class="kd">public</span> <span class="n">String</span> <span class="nf">test1</span><span class="o">(){</span>
        <span class="c1">//转发
</span><span class="c1"></span>        <span class="k">return</span> <span class="s">&#34;test&#34;</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">&#34;/rsm2/t2&#34;</span><span class="o">)</span>
    <span class="kd">public</span> <span class="n">String</span> <span class="nf">test2</span><span class="o">(){</span>
        <span class="c1">//重定向
</span><span class="c1"></span>        <span class="k">return</span> <span class="s">&#34;redirect:/index.jsp&#34;</span><span class="o">;</span>
        <span class="c1">//return &#34;redirect:hello.do&#34;; //hello.do为另一个请求/
</span><span class="c1"></span>    <span class="o">}</span>

<span class="o">}</span>
</code></pre></div><h2 id="数据处理">数据处理</h2>
<h3 id="处理提交数据">处理提交数据</h3>
<p><strong>1、提交的域名称和处理方法的参数名一致</strong></p>
<p>提交数据 : http://localhost:8080/hello?name=lbqaq</p>
<p>处理方法 :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">&#34;/hello&#34;</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">hello</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">){</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">name</span><span class="o">);</span>
    <span class="k">return</span> <span class="s">&#34;hello&#34;</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><p>后台输出 : lbqaq</p>
<p><strong>2、提交的域名称和处理方法的参数名不一致</strong></p>
<p>提交数据 : http://localhost:8080/hello?username=lbqaq</p>
<p>处理方法 :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="c1">//@RequestParam(&#34;username&#34;) : username提交的域的名称 .
</span><span class="c1"></span><span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">&#34;/hello&#34;</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">hello</span><span class="o">(</span><span class="nd">@RequestParam</span><span class="o">(</span><span class="s">&#34;username&#34;</span><span class="o">)</span> <span class="n">String</span> <span class="n">name</span><span class="o">){</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">name</span><span class="o">);</span>
    <span class="k">return</span> <span class="s">&#34;hello&#34;</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><p>后台输出 : lbqaq</p>
<p><strong>3、提交的是一个对象</strong></p>
<p>要求提交的表单域和对象的属性名一致  , 参数使用对象即可</p>
<p>1、实体类</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">User</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kt">int</span> <span class="n">id</span><span class="o">;</span>
    <span class="kd">private</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">int</span> <span class="n">age</span><span class="o">;</span>
    <span class="c1">//构造
</span><span class="c1"></span>    <span class="c1">//get/set
</span><span class="c1"></span>    <span class="c1">//tostring()
</span><span class="c1"></span><span class="o">}</span>
</code></pre></div><p>2、提交数据 : http://localhost:8080/mvc04/user?name=lbqaq&amp;id=1&amp;age=15</p>
<p>3、处理方法 :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">&#34;/user&#34;</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">user</span><span class="o">(</span><span class="n">User</span> <span class="n">user</span><span class="o">){</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">user</span><span class="o">);</span>
    <span class="k">return</span> <span class="s">&#34;hello&#34;</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><p>后台输出 : User { id=1, name=&lsquo;lbqaq&rsquo;, age=15 }</p>
<p>说明：如果使用对象的话，前端传递的参数名和对象名必须一致，否则就是null。</p>
<h3 id="数据显示到前端">数据显示到前端</h3>
<p><strong>第一种 : 通过ModelAndView</strong></p>
<p>我们前面一直都是如此 . 就不过多解释</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ControllerTest1</span> <span class="kd">implements</span> <span class="n">Controller</span> <span class="o">{</span>

    <span class="kd">public</span> <span class="n">ModelAndView</span> <span class="nf">handleRequest</span><span class="o">(</span><span class="n">HttpServletRequest</span> <span class="n">httpServletRequest</span><span class="o">,</span> <span class="n">HttpServletResponse</span> <span class="n">httpServletResponse</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
        <span class="c1">//返回一个模型视图对象
</span><span class="c1"></span>        <span class="n">ModelAndView</span> <span class="n">mv</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ModelAndView</span><span class="o">();</span>
        <span class="n">mv</span><span class="o">.</span><span class="na">addObject</span><span class="o">(</span><span class="s">&#34;msg&#34;</span><span class="o">,</span><span class="s">&#34;ControllerTest1&#34;</span><span class="o">);</span>
        <span class="n">mv</span><span class="o">.</span><span class="na">setViewName</span><span class="o">(</span><span class="s">&#34;test&#34;</span><span class="o">);</span>
        <span class="k">return</span> <span class="n">mv</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p><strong>第二种 : 通过ModelMap</strong></p>
<p>ModelMap</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">&#34;/hello&#34;</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">hello</span><span class="o">(</span><span class="nd">@RequestParam</span><span class="o">(</span><span class="s">&#34;username&#34;</span><span class="o">)</span> <span class="n">String</span> <span class="n">name</span><span class="o">,</span> <span class="n">ModelMap</span> <span class="n">model</span><span class="o">){</span>
    <span class="c1">//封装要显示到视图中的数据
</span><span class="c1"></span>    <span class="c1">//相当于req.setAttribute(&#34;name&#34;,name);
</span><span class="c1"></span>    <span class="n">model</span><span class="o">.</span><span class="na">addAttribute</span><span class="o">(</span><span class="s">&#34;name&#34;</span><span class="o">,</span><span class="n">name</span><span class="o">);</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">name</span><span class="o">);</span>
    <span class="k">return</span> <span class="s">&#34;hello&#34;</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><p><strong>第三种 : 通过Model</strong></p>
<p>Model</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">&#34;/ct2/hello&#34;</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">hello</span><span class="o">(</span><span class="nd">@RequestParam</span><span class="o">(</span><span class="s">&#34;username&#34;</span><span class="o">)</span> <span class="n">String</span> <span class="n">name</span><span class="o">,</span> <span class="n">Model</span> <span class="n">model</span><span class="o">){</span>
    <span class="c1">//封装要显示到视图中的数据
</span><span class="c1"></span>    <span class="c1">//相当于req.setAttribute(&#34;name&#34;,name);
</span><span class="c1"></span>    <span class="n">model</span><span class="o">.</span><span class="na">addAttribute</span><span class="o">(</span><span class="s">&#34;msg&#34;</span><span class="o">,</span><span class="n">name</span><span class="o">);</span>
    <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">name</span><span class="o">);</span>
    <span class="k">return</span> <span class="s">&#34;test&#34;</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><h3 id="对比">对比</h3>
<p>就对于新手而言简单来说使用区别就是：</p>
<ul>
<li>Model 只有寥寥几个方法只适合用于储存数据，简化了新手对于Model对象的操作和理解；</li>
<li>ModelMap 继承了 LinkedMap ，除了实现了自身的一些方法，同样的继承 LinkedMap 的方法和特性；</li>
<li>ModelAndView 可以在储存数据的同时，可以进行设置返回的逻辑视图，进行控制展示层的跳转。</li>
</ul>
<p>当然更多的以后开发考虑的更多的是性能和优化，就不能单单仅限于此的了解。</p>
<p>这里都是概念性的内容，所以就直接复制笔记了😌</p>
<h4 id="解决乱码">解决乱码</h4>
<p>直接把Spring的乱码处理器放入<code>web.xml</code>里</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;filter&gt;</span>
   <span class="nt">&lt;filter-name&gt;</span>encoding<span class="nt">&lt;/filter-name&gt;</span>
   <span class="nt">&lt;filter-class&gt;</span>org.springframework.web.filter.CharacterEncodingFilter<span class="nt">&lt;/filter-class&gt;</span>
   <span class="nt">&lt;init-param&gt;</span>
       <span class="nt">&lt;param-name&gt;</span>encoding<span class="nt">&lt;/param-name&gt;</span>
       <span class="nt">&lt;param-value&gt;</span>utf-8<span class="nt">&lt;/param-value&gt;</span>
   <span class="nt">&lt;/init-param&gt;</span>
<span class="nt">&lt;/filter&gt;</span>
<span class="nt">&lt;filter-mapping&gt;</span>
   <span class="nt">&lt;filter-name&gt;</span>encoding<span class="nt">&lt;/filter-name&gt;</span>
   <span class="nt">&lt;url-pattern&gt;</span>/*<span class="nt">&lt;/url-pattern&gt;</span>
<span class="nt">&lt;/filter-mapping&gt;</span>
</code></pre></div><h2 id="json">JSON</h2>
<ul>
<li>JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式，目前使用特别广泛。</li>
<li>采用完全独立于编程语言的<strong>文本格式</strong>来存储和表示数据。</li>
<li>简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。</li>
<li>易于人阅读和编写，同时也易于机器解析和生成，并有效地提升网络传输效率。</li>
</ul>
<h3 id="使用jackson">使用Jackson</h3>
<ol>
<li>
<p>导入依赖</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="c">&lt;!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --&gt;</span>
<span class="nt">&lt;dependency&gt;</span>
    <span class="nt">&lt;groupId&gt;</span>com.fasterxml.jackson.core<span class="nt">&lt;/groupId&gt;</span>
    <span class="nt">&lt;artifactId&gt;</span>jackson-core<span class="nt">&lt;/artifactId&gt;</span>
    <span class="nt">&lt;version&gt;</span>2.12.4<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div></li>
<li>
<p>编写Controller</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="nd">@Controller</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserController</span> <span class="o">{</span>

   <span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">&#34;/json1&#34;</span><span class="o">)</span>
   <span class="nd">@ResponseBody</span>
   <span class="kd">public</span> <span class="n">String</span> <span class="nf">json1</span><span class="o">()</span> <span class="kd">throws</span> <span class="n">JsonProcessingException</span> <span class="o">{</span>
       <span class="c1">//创建一个jackson的对象映射器，用来解析数据
</span><span class="c1"></span>       <span class="n">ObjectMapper</span> <span class="n">mapper</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ObjectMapper</span><span class="o">();</span>
       <span class="c1">//创建一个对象
</span><span class="c1"></span>       <span class="n">User</span> <span class="n">user</span> <span class="o">=</span> <span class="k">new</span> <span class="n">User</span><span class="o">(</span><span class="s">&#34;小明&#34;</span><span class="o">,</span> <span class="n">3</span><span class="o">,</span> <span class="s">&#34;男&#34;</span><span class="o">);</span>
       <span class="c1">//将我们的对象解析成为json格式
</span><span class="c1"></span>       <span class="n">String</span> <span class="n">str</span> <span class="o">=</span> <span class="n">mapper</span><span class="o">.</span><span class="na">writeValueAsString</span><span class="o">(</span><span class="n">user</span><span class="o">);</span>
       <span class="c1">//由于@ResponseBody注解，这里会将str转成json格式返回；十分方便
</span><span class="c1"></span>       <span class="k">return</span> <span class="n">str</span><span class="o">;</span>
  <span class="o">}</span>
</code></pre></div><p>如果出现乱码，可以指定编码格式为UTF8来解决</p>
<p><code>@RequestMapping(value = &quot;/json1&quot;,produces = &quot;application/json;charset=utf-8&quot;)</code></p>
</li>
</ol>
<p>这样处理乱码还是太麻烦了，可以让Spring统一管理，在SpringMVC的配置文件里加上下面的代码。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;mvc:annotation-driven&gt;</span>
   <span class="nt">&lt;mvc:message-converters</span> <span class="na">register-defaults=</span><span class="s">&#34;true&#34;</span><span class="nt">&gt;</span>
       <span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">&#34;org.springframework.http.converter.StringHttpMessageConverter&#34;</span><span class="nt">&gt;</span>
           <span class="nt">&lt;constructor-arg</span> <span class="na">value=</span><span class="s">&#34;UTF-8&#34;</span><span class="nt">/&gt;</span>
       <span class="nt">&lt;/bean&gt;</span>
       <span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">&#34;org.springframework.http.converter.json.MappingJackson2HttpMessageConverter&#34;</span><span class="nt">&gt;</span>
           <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&#34;objectMapper&#34;</span><span class="nt">&gt;</span>
               <span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">&#34;org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean&#34;</span><span class="nt">&gt;</span>
                   <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&#34;failOnEmptyBeans&#34;</span> <span class="na">value=</span><span class="s">&#34;false&#34;</span><span class="nt">/&gt;</span>
               <span class="nt">&lt;/bean&gt;</span>
           <span class="nt">&lt;/property&gt;</span>
       <span class="nt">&lt;/bean&gt;</span>
   <span class="nt">&lt;/mvc:message-converters&gt;</span>
<span class="nt">&lt;/mvc:annotation-driven&gt;</span>
</code></pre></div><p>在类上直接使用 <code>@RestController</code> ，这样子，里面所有的方法都只会返回 json 字符串了，不用再每一个都添加<code>@ResponseBody</code> ！我们在前后端分离开发中，一般都使用 <code>@RestController</code> ，十分便捷！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="nd">@RestController</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserController</span> <span class="o">{</span>
    <span class="c1">//produces:指定响应体返回类型和编码
</span><span class="c1"></span>    <span class="nd">@RequestMapping</span><span class="o">(</span><span class="n">value</span> <span class="o">=</span> <span class="s">&#34;/json1&#34;</span><span class="o">)</span>
    <span class="kd">public</span> <span class="n">String</span> <span class="nf">json1</span><span class="o">()</span> <span class="kd">throws</span> <span class="n">JsonProcessingException</span> <span class="o">{</span>
        <span class="c1">//创建一个jackson的对象映射器，用来解析数据
</span><span class="c1"></span>        <span class="n">ObjectMapper</span> <span class="n">mapper</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ObjectMapper</span><span class="o">();</span>
        <span class="c1">//创建一个对象
</span><span class="c1"></span>        <span class="n">User</span> <span class="n">user</span> <span class="o">=</span> <span class="k">new</span> <span class="n">User</span><span class="o">(</span><span class="s">&#34;小明&#34;</span><span class="o">,</span> <span class="n">3</span><span class="o">,</span> <span class="s">&#34;男&#34;</span><span class="o">);</span>
        <span class="c1">//将我们的对象解析成为json格式
</span><span class="c1"></span>        <span class="n">String</span> <span class="n">str</span> <span class="o">=</span> <span class="n">mapper</span><span class="o">.</span><span class="na">writeValueAsString</span><span class="o">(</span><span class="n">user</span><span class="o">);</span>
        <span class="c1">//由于@ResponseBody注解，这里会将str转成json格式返回；十分方便
</span><span class="c1"></span>        <span class="k">return</span> <span class="n">str</span><span class="o">;</span>
    <span class="o">}</span>

<span class="o">}</span>
</code></pre></div><p>自定义工具类，可以是JSON转换变得更简单</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">JsonUtils</span> <span class="o">{</span>
   
   <span class="kd">public</span> <span class="kd">static</span> <span class="n">String</span> <span class="nf">getJson</span><span class="o">(</span><span class="n">Object</span> <span class="n">object</span><span class="o">)</span> <span class="o">{</span>
       <span class="k">return</span> <span class="n">getJson</span><span class="o">(</span><span class="n">object</span><span class="o">,</span><span class="s">&#34;yyyy-MM-dd HH:mm:ss&#34;</span><span class="o">);</span>
  <span class="o">}</span>

   <span class="kd">public</span> <span class="kd">static</span> <span class="n">String</span> <span class="nf">getJson</span><span class="o">(</span><span class="n">Object</span> <span class="n">object</span><span class="o">,</span><span class="n">String</span> <span class="n">dateFormat</span><span class="o">)</span> <span class="o">{</span>
       <span class="n">ObjectMapper</span> <span class="n">mapper</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ObjectMapper</span><span class="o">();</span>
       <span class="c1">//不使用时间差的方式
</span><span class="c1"></span>       <span class="n">mapper</span><span class="o">.</span><span class="na">configure</span><span class="o">(</span><span class="n">SerializationFeature</span><span class="o">.</span><span class="na">WRITE_DATES_AS_TIMESTAMPS</span><span class="o">,</span> <span class="kc">false</span><span class="o">);</span>
       <span class="c1">//自定义日期格式对象
</span><span class="c1"></span>       <span class="n">SimpleDateFormat</span> <span class="n">sdf</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SimpleDateFormat</span><span class="o">(</span><span class="n">dateFormat</span><span class="o">);</span>
       <span class="c1">//指定日期格式
</span><span class="c1"></span>       <span class="n">mapper</span><span class="o">.</span><span class="na">setDateFormat</span><span class="o">(</span><span class="n">sdf</span><span class="o">);</span>
       <span class="k">try</span> <span class="o">{</span>
           <span class="k">return</span> <span class="n">mapper</span><span class="o">.</span><span class="na">writeValueAsString</span><span class="o">(</span><span class="n">object</span><span class="o">);</span>
      <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">JsonProcessingException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
           <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
      <span class="o">}</span>
       <span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><h3 id="使用fastjson">使用FastJson</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="c">&lt;!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --&gt;</span>
<span class="nt">&lt;dependency&gt;</span>
    <span class="nt">&lt;groupId&gt;</span>com.alibaba<span class="nt">&lt;/groupId&gt;</span>
    <span class="nt">&lt;artifactId&gt;</span>fastjson<span class="nt">&lt;/artifactId&gt;</span>
    <span class="nt">&lt;version&gt;</span>1.2.78<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div><p>为了使<code>@RestController</code>有效，需要在Spring配置里加上下面的内容</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;mvc:annotation-driven&gt;</span>
    <span class="nt">&lt;mvc:message-converters</span> <span class="na">register-defaults=</span><span class="s">&#34;true&#34;</span><span class="nt">&gt;</span>
        <span class="c">&lt;!-- 配置Fastjson支持 --&gt;</span>
        <span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">&#34;com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter&#34;</span><span class="nt">&gt;</span>
            <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&#34;supportedMediaTypes&#34;</span><span class="nt">&gt;</span>
                <span class="nt">&lt;list&gt;</span>
                    <span class="nt">&lt;value&gt;</span>application/json<span class="nt">&lt;/value&gt;</span>
                    <span class="nt">&lt;value&gt;</span>text/html;charset=UTF-8<span class="nt">&lt;/value&gt;</span>
                <span class="nt">&lt;/list&gt;</span>
            <span class="nt">&lt;/property&gt;</span>
        <span class="nt">&lt;/bean&gt;</span>
    <span class="nt">&lt;/mvc:message-converters&gt;</span>
<span class="nt">&lt;/mvc:annotation-driven&gt;</span>
</code></pre></div><p>fastjson 三个主要的类：</p>
<p><strong>JSONObject  代表 json 对象</strong></p>
<ul>
<li>JSONObject实现了Map接口, 猜想 JSONObject底层操作是由Map实现的。</li>
<li>JSONObject对应json对象，通过各种形式的get()方法可以获取json对象中的数据，也可利用诸如size()，isEmpty()等方法获取&quot;键：值&quot;对的个数和判断是否为空。其本质是通过实现Map接口并调用接口中的方法完成的。</li>
</ul>
<p><strong>JSONArray  代表 json 对象数组</strong></p>
<ul>
<li>内部是有List接口中的方法来完成操作的。</li>
</ul>
<p><strong>JSON代表 JSONObject和JSONArray的转化</strong></p>
<ul>
<li>JSON类源码分析与使用</li>
<li>仔细观察这些方法，主要是实现json对象，json对象数组，javabean对象，json字符串之间的相互转化。</li>
</ul>
<p>测试代码</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java">
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">FastJsonDemo</span> <span class="o">{</span>
   <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
       <span class="c1">//创建一个对象
</span><span class="c1"></span>       <span class="n">User</span> <span class="n">user1</span> <span class="o">=</span> <span class="k">new</span> <span class="n">User</span><span class="o">(</span><span class="s">&#34;1号&#34;</span><span class="o">,</span> <span class="n">3</span><span class="o">,</span> <span class="s">&#34;男&#34;</span><span class="o">);</span>
       <span class="n">User</span> <span class="n">user2</span> <span class="o">=</span> <span class="k">new</span> <span class="n">User</span><span class="o">(</span><span class="s">&#34;2号&#34;</span><span class="o">,</span> <span class="n">3</span><span class="o">,</span> <span class="s">&#34;男&#34;</span><span class="o">);</span>
       <span class="n">User</span> <span class="n">user3</span> <span class="o">=</span> <span class="k">new</span> <span class="n">User</span><span class="o">(</span><span class="s">&#34;3号&#34;</span><span class="o">,</span> <span class="n">3</span><span class="o">,</span> <span class="s">&#34;男&#34;</span><span class="o">);</span>
       <span class="n">User</span> <span class="n">user4</span> <span class="o">=</span> <span class="k">new</span> <span class="n">User</span><span class="o">(</span><span class="s">&#34;4号&#34;</span><span class="o">,</span> <span class="n">3</span><span class="o">,</span> <span class="s">&#34;男&#34;</span><span class="o">);</span>
       <span class="n">List</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;</span> <span class="n">list</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;();</span>
       <span class="n">list</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">user1</span><span class="o">);</span>
       <span class="n">list</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">user2</span><span class="o">);</span>
       <span class="n">list</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">user3</span><span class="o">);</span>
       <span class="n">list</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">user4</span><span class="o">);</span>

       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;*******Java对象 转 JSON字符串*******&#34;</span><span class="o">);</span>
       <span class="n">String</span> <span class="n">str1</span> <span class="o">=</span> <span class="n">JSON</span><span class="o">.</span><span class="na">toJSONString</span><span class="o">(</span><span class="n">list</span><span class="o">);</span>
       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;JSON.toJSONString(list)==&gt;&#34;</span><span class="o">+</span><span class="n">str1</span><span class="o">);</span>
       <span class="n">String</span> <span class="n">str2</span> <span class="o">=</span> <span class="n">JSON</span><span class="o">.</span><span class="na">toJSONString</span><span class="o">(</span><span class="n">user1</span><span class="o">);</span>
       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;JSON.toJSONString(user1)==&gt;&#34;</span><span class="o">+</span><span class="n">str2</span><span class="o">);</span>

       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;\n****** JSON字符串 转 Java对象*******&#34;</span><span class="o">);</span>
       <span class="n">User</span> <span class="n">jp_user1</span><span class="o">=</span><span class="n">JSON</span><span class="o">.</span><span class="na">parseObject</span><span class="o">(</span><span class="n">str2</span><span class="o">,</span><span class="n">User</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;JSON.parseObject(str2,User.class)==&gt;&#34;</span><span class="o">+</span><span class="n">jp_user1</span><span class="o">);</span>

       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;\n****** Java对象 转 JSON对象 ******&#34;</span><span class="o">);</span>
       <span class="n">JSONObject</span> <span class="n">jsonObject1</span> <span class="o">=</span> <span class="o">(</span><span class="n">JSONObject</span><span class="o">)</span> <span class="n">JSON</span><span class="o">.</span><span class="na">toJSON</span><span class="o">(</span><span class="n">user2</span><span class="o">);</span>
       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;(JSONObject) JSON.toJSON(user2)==&gt;&#34;</span><span class="o">+</span><span class="n">jsonObject1</span><span class="o">.</span><span class="na">getString</span><span class="o">(</span><span class="s">&#34;name&#34;</span><span class="o">));</span>

       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;\n****** JSON对象 转 Java对象 ******&#34;</span><span class="o">);</span>
       <span class="n">User</span> <span class="n">to_java_user</span> <span class="o">=</span> <span class="n">JSON</span><span class="o">.</span><span class="na">toJavaObject</span><span class="o">(</span><span class="n">jsonObject1</span><span class="o">,</span> <span class="n">User</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;JSON.toJavaObject(jsonObject1, User.class)==&gt;&#34;</span><span class="o">+</span><span class="n">to_java_user</span><span class="o">);</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div><p>Jackson刚刚测试没成功，还是选择FastJson吧😇。</p>
<h2 id="拦截器">拦截器</h2>
<h3 id="概述-1">概述</h3>
<p>SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。</p>
<p>**过滤器与拦截器的区别：**拦截器是AOP思想的具体应用。</p>
<p><strong>过滤器</strong></p>
<ul>
<li>servlet规范中的一部分，任何java web工程都可以使用</li>
<li>在url-pattern中配置了/*之后，可以对所有要访问的资源进行拦截</li>
</ul>
<p><strong>拦截器</strong></p>
<ul>
<li>拦截器是SpringMVC框架自己的，只有使用了SpringMVC框架的工程才能使用</li>
<li>拦截器只会拦截访问的控制器方法， 如果访问的是jsp/html/css/image/js是不会进行拦截的</li>
</ul>
<h3 id="使用方法">使用方法</h3>
<ol>
<li>
<p>自定义拦截器需要实现接口<code>HandlerInterceptor</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyInterceptor</span> <span class="kd">implements</span> <span class="n">HandlerInterceptor</span> <span class="o">{</span>
   <span class="c1">//在请求处理的方法之前执行
</span><span class="c1"></span>   <span class="c1">//如果返回true执行下一个拦截器
</span><span class="c1"></span>   <span class="c1">//如果返回false就不执行下一个拦截器
</span><span class="c1"></span>   <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">preHandle</span><span class="o">(</span><span class="n">HttpServletRequest</span> <span class="n">httpServletRequest</span><span class="o">,</span> <span class="n">HttpServletResponse</span> <span class="n">httpServletResponse</span><span class="o">,</span> <span class="n">Object</span> <span class="n">o</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;------------处理前------------&#34;</span><span class="o">);</span>
       <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
  <span class="o">}</span>

   <span class="c1">//在请求处理方法执行之后执行
</span><span class="c1"></span>   <span class="kd">public</span> <span class="kt">void</span> <span class="nf">postHandle</span><span class="o">(</span><span class="n">HttpServletRequest</span> <span class="n">httpServletRequest</span><span class="o">,</span> <span class="n">HttpServletResponse</span> <span class="n">httpServletResponse</span><span class="o">,</span> <span class="n">Object</span> <span class="n">o</span><span class="o">,</span> <span class="n">ModelAndView</span> <span class="n">modelAndView</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;------------处理后------------&#34;</span><span class="o">);</span>
  <span class="o">}</span>

   <span class="c1">//在dispatcherServlet处理后执行,做清理工作.
</span><span class="c1"></span>   <span class="kd">public</span> <span class="kt">void</span> <span class="nf">afterCompletion</span><span class="o">(</span><span class="n">HttpServletRequest</span> <span class="n">httpServletRequest</span><span class="o">,</span> <span class="n">HttpServletResponse</span> <span class="n">httpServletResponse</span><span class="o">,</span> <span class="n">Object</span> <span class="n">o</span><span class="o">,</span> <span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;------------清理------------&#34;</span><span class="o">);</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></li>
<li>
<p>在springmvc的配置文件中配置拦截器</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="c">&lt;!--关于拦截器的配置--&gt;</span>
<span class="nt">&lt;mvc:interceptors&gt;</span>
   <span class="nt">&lt;mvc:interceptor&gt;</span>
       <span class="c">&lt;!--/** 包括路径及其子路径--&gt;</span>
       <span class="c">&lt;!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截--&gt;</span>
       <span class="c">&lt;!--/admin/** 拦截的是/admin/下的所有--&gt;</span>
       <span class="nt">&lt;mvc:mapping</span> <span class="na">path=</span><span class="s">&#34;/**&#34;</span><span class="nt">/&gt;</span>
       <span class="c">&lt;!--bean配置的就是拦截器--&gt;</span>
       <span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">&#34;top.lbqaq.interceptor.MyInterceptor&#34;</span><span class="nt">/&gt;</span>
   <span class="nt">&lt;/mvc:interceptor&gt;</span>
<span class="nt">&lt;/mvc:interceptors&gt;</span>
</code></pre></div></li>
</ol>
<p>执行顺序如下：</p>
<pre><code>------------处理前------------
Controller方法
------------处理后------------
------------清理------------
</code></pre><p>拦截器可以用来做登录验证等等内容，这里就不展开了（才不是懒得写）</p>
<h2 id="文件传输">文件传输</h2>
<p>文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传，但是SpringMVC上下文中默认没有装配MultipartResolver，因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能，则需要在上下文中配置MultipartResolver。</p>
<p>前端表单要求：为了能上传文件，必须将表单的method设置为POST，并将enctype设置为multipart/form-data。只有在这样的情况下，浏览器才会把用户选择的文件以二进制数据发送给服务器；</p>
<p><strong>对表单中的 enctype 属性做个详细的说明：</strong></p>
<ul>
<li>application/x-www=form-urlencoded：默认方式，只处理表单域中的 value 属性值，采用这种编码方式的表单会将表单域中的值处理成 URL 编码方式。</li>
<li>multipart/form-data：这种编码方式会以二进制流的方式来处理表单数据，这种编码方式会把文件域指定文件的内容也封装到请求参数中，不会对字符编码。</li>
<li>text/plain：除了把空格转换为 &ldquo;+&rdquo; 号外，其他字符都不做编码处理，这种方式适用直接通过表单发送邮件。</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="p">&lt;</span><span class="nt">form</span> <span class="na">action</span><span class="o">=</span><span class="s">&#34;&#34;</span> <span class="na">enctype</span><span class="o">=</span><span class="s">&#34;multipart/form-data&#34;</span> <span class="na">method</span><span class="o">=</span><span class="s">&#34;post&#34;</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;file&#34;</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;file&#34;</span><span class="p">/&gt;</span>
    <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;submit&#34;</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">form</span><span class="p">&gt;</span>
</code></pre></div><h3 id="文件上传">文件上传</h3>
<ol>
<li>
<p>导入依赖包</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="c">&lt;!--文件上传--&gt;</span>
<span class="nt">&lt;dependency&gt;</span>
   <span class="nt">&lt;groupId&gt;</span>commons-fileupload<span class="nt">&lt;/groupId&gt;</span>
   <span class="nt">&lt;artifactId&gt;</span>commons-fileupload<span class="nt">&lt;/artifactId&gt;</span>
   <span class="nt">&lt;version&gt;</span>1.3.3<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
<span class="c">&lt;!--servlet-api导入高版本的--&gt;</span>
<span class="nt">&lt;dependency&gt;</span>
   <span class="nt">&lt;groupId&gt;</span>javax.servlet<span class="nt">&lt;/groupId&gt;</span>
   <span class="nt">&lt;artifactId&gt;</span>javax.servlet-api<span class="nt">&lt;/artifactId&gt;</span>
   <span class="nt">&lt;version&gt;</span>4.0.1<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div></li>
<li>
<p>配置<code>multipartResolver</code></p>
<p><strong>这个bena的id必须为：multipartResolver ， 否则上传文件会报400的错误！</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="c">&lt;!--文件上传配置--&gt;</span>
<span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&#34;multipartResolver&#34;</span>  <span class="na">class=</span><span class="s">&#34;org.springframework.web.multipart.commons.CommonsMultipartResolver&#34;</span><span class="nt">&gt;</span>
   <span class="c">&lt;!-- 请求的编码格式，必须和jSP的pageEncoding属性一致，以便正确读取表单的内容，默认为ISO-8859-1 --&gt;</span>
   <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&#34;defaultEncoding&#34;</span> <span class="na">value=</span><span class="s">&#34;utf-8&#34;</span><span class="nt">/&gt;</span>
   <span class="c">&lt;!-- 上传文件大小上限，单位为字节（10485760=10M） --&gt;</span>
   <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&#34;maxUploadSize&#34;</span> <span class="na">value=</span><span class="s">&#34;10485760&#34;</span><span class="nt">/&gt;</span>
   <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&#34;maxInMemorySize&#34;</span> <span class="na">value=</span><span class="s">&#34;40960&#34;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/bean&gt;</span>
</code></pre></div></li>
<li>
<p>编写前端页面</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="p">&lt;</span><span class="nt">form</span> <span class="na">action</span><span class="o">=</span><span class="s">&#34;/upload&#34;</span> <span class="na">enctype</span><span class="o">=</span><span class="s">&#34;multipart/form-data&#34;</span> <span class="na">method</span><span class="o">=</span><span class="s">&#34;post&#34;</span><span class="p">&gt;</span>
 <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;file&#34;</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;file&#34;</span><span class="p">/&gt;</span>
 <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;submit&#34;</span> <span class="na">value</span><span class="o">=</span><span class="s">&#34;upload&#34;</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">form</span><span class="p">&gt;</span>
</code></pre></div></li>
<li>
<p>配置Controller</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.kuang.controller</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">org.springframework.stereotype.Controller</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.web.bind.annotation.RequestMapping</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.web.bind.annotation.RequestParam</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.web.multipart.commons.CommonsMultipartFile</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">javax.servlet.http.HttpServletRequest</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.*</span><span class="o">;</span>

<span class="nd">@Controller</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">FileController</span> <span class="o">{</span>
   <span class="c1">//@RequestParam(&#34;file&#34;) 将name=file控件得到的文件封装成CommonsMultipartFile 对象
</span><span class="c1"></span>   <span class="c1">//批量上传CommonsMultipartFile则为数组即可
</span><span class="c1"></span>   <span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">&#34;/upload&#34;</span><span class="o">)</span>
   <span class="kd">public</span> <span class="n">String</span> <span class="nf">fileUpload</span><span class="o">(</span><span class="nd">@RequestParam</span><span class="o">(</span><span class="s">&#34;file&#34;</span><span class="o">)</span> <span class="n">CommonsMultipartFile</span> <span class="n">file</span> <span class="o">,</span> <span class="n">HttpServletRequest</span> <span class="n">request</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">IOException</span> <span class="o">{</span>

       <span class="c1">//获取文件名 : file.getOriginalFilename();
</span><span class="c1"></span>       <span class="n">String</span> <span class="n">uploadFileName</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="na">getOriginalFilename</span><span class="o">();</span>

       <span class="c1">//如果文件名为空，直接回到首页！
</span><span class="c1"></span>       <span class="k">if</span> <span class="o">(</span><span class="s">&#34;&#34;</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">uploadFileName</span><span class="o">)){</span>
           <span class="k">return</span> <span class="s">&#34;redirect:/index.jsp&#34;</span><span class="o">;</span>
      <span class="o">}</span>
       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;上传文件名 : &#34;</span><span class="o">+</span><span class="n">uploadFileName</span><span class="o">);</span>

       <span class="c1">//上传路径保存设置
</span><span class="c1"></span>       <span class="n">String</span> <span class="n">path</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="na">getServletContext</span><span class="o">().</span><span class="na">getRealPath</span><span class="o">(</span><span class="s">&#34;/upload&#34;</span><span class="o">);</span>
       <span class="c1">//如果路径不存在，创建一个
</span><span class="c1"></span>       <span class="n">File</span> <span class="n">realPath</span> <span class="o">=</span> <span class="k">new</span> <span class="n">File</span><span class="o">(</span><span class="n">path</span><span class="o">);</span>
       <span class="k">if</span> <span class="o">(!</span><span class="n">realPath</span><span class="o">.</span><span class="na">exists</span><span class="o">()){</span>
           <span class="n">realPath</span><span class="o">.</span><span class="na">mkdir</span><span class="o">();</span>
      <span class="o">}</span>
       <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;上传文件保存地址：&#34;</span><span class="o">+</span><span class="n">realPath</span><span class="o">);</span>

       <span class="n">InputStream</span> <span class="n">is</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="na">getInputStream</span><span class="o">();</span> <span class="c1">//文件输入流
</span><span class="c1"></span>       <span class="n">OutputStream</span> <span class="n">os</span> <span class="o">=</span> <span class="k">new</span> <span class="n">FileOutputStream</span><span class="o">(</span><span class="k">new</span> <span class="n">File</span><span class="o">(</span><span class="n">realPath</span><span class="o">,</span><span class="n">uploadFileName</span><span class="o">));</span> <span class="c1">//文件输出流
</span><span class="c1"></span>
       <span class="c1">//读取写出
</span><span class="c1"></span>       <span class="kt">int</span> <span class="n">len</span><span class="o">=</span><span class="n">0</span><span class="o">;</span>
       <span class="kt">byte</span><span class="o">[]</span> <span class="n">buffer</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">byte</span><span class="o">[</span><span class="n">1024</span><span class="o">];</span>
       <span class="k">while</span> <span class="o">((</span><span class="n">len</span><span class="o">=</span><span class="n">is</span><span class="o">.</span><span class="na">read</span><span class="o">(</span><span class="n">buffer</span><span class="o">))!=-</span><span class="n">1</span><span class="o">){</span>
           <span class="n">os</span><span class="o">.</span><span class="na">write</span><span class="o">(</span><span class="n">buffer</span><span class="o">,</span><span class="n">0</span><span class="o">,</span><span class="n">len</span><span class="o">);</span>
           <span class="n">os</span><span class="o">.</span><span class="na">flush</span><span class="o">();</span>
      <span class="o">}</span>
       <span class="n">os</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
       <span class="n">is</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
       <span class="k">return</span> <span class="s">&#34;redirect:/index.jsp&#34;</span><span class="o">;</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></li>
</ol>
<p><strong>方法二：使用file.Transto 来保存上传的文件</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="cm">/*
</span><span class="cm">* 采用file.Transto 来保存上传的文件
</span><span class="cm">*/</span>
<span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">&#34;/upload2&#34;</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">String</span>  <span class="nf">fileUpload2</span><span class="o">(</span><span class="nd">@RequestParam</span><span class="o">(</span><span class="s">&#34;file&#34;</span><span class="o">)</span> <span class="n">CommonsMultipartFile</span> <span class="n">file</span><span class="o">,</span> <span class="n">HttpServletRequest</span> <span class="n">request</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">IOException</span> <span class="o">{</span>

   <span class="c1">//上传路径保存设置
</span><span class="c1"></span>   <span class="n">String</span> <span class="n">path</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="na">getServletContext</span><span class="o">().</span><span class="na">getRealPath</span><span class="o">(</span><span class="s">&#34;/upload&#34;</span><span class="o">);</span>
   <span class="n">File</span> <span class="n">realPath</span> <span class="o">=</span> <span class="k">new</span> <span class="n">File</span><span class="o">(</span><span class="n">path</span><span class="o">);</span>
   <span class="k">if</span> <span class="o">(!</span><span class="n">realPath</span><span class="o">.</span><span class="na">exists</span><span class="o">()){</span>
       <span class="n">realPath</span><span class="o">.</span><span class="na">mkdir</span><span class="o">();</span>
  <span class="o">}</span>
   <span class="c1">//上传文件地址
</span><span class="c1"></span>   <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&#34;上传文件保存地址：&#34;</span><span class="o">+</span><span class="n">realPath</span><span class="o">);</span>

   <span class="c1">//通过CommonsMultipartFile的方法直接写文件（注意这个时候）
</span><span class="c1"></span>   <span class="n">file</span><span class="o">.</span><span class="na">transferTo</span><span class="o">(</span><span class="k">new</span> <span class="n">File</span><span class="o">(</span><span class="n">realPath</span> <span class="o">+</span><span class="s">&#34;/&#34;</span><span class="o">+</span> <span class="n">file</span><span class="o">.</span><span class="na">getOriginalFilename</span><span class="o">()));</span>

   <span class="k">return</span> <span class="s">&#34;redirect:/index.jsp&#34;</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><h3 id="文件下载">文件下载</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="nd">@RequestMapping</span><span class="o">(</span><span class="n">value</span><span class="o">=</span><span class="s">&#34;/download&#34;</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">downloads</span><span class="o">(</span><span class="n">HttpServletResponse</span> <span class="n">response</span> <span class="o">,</span><span class="n">HttpServletRequest</span> <span class="n">request</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span><span class="o">{</span>
   <span class="c1">//要下载的图片地址
</span><span class="c1"></span>   <span class="n">String</span>  <span class="n">path</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="na">getServletContext</span><span class="o">().</span><span class="na">getRealPath</span><span class="o">(</span><span class="s">&#34;/upload&#34;</span><span class="o">);</span>
   <span class="n">String</span>  <span class="n">fileName</span> <span class="o">=</span> <span class="s">&#34;基础语法.jpg&#34;</span><span class="o">;</span>

   <span class="c1">//1、设置response 响应头
</span><span class="c1"></span>   <span class="n">response</span><span class="o">.</span><span class="na">reset</span><span class="o">();</span> <span class="c1">//设置页面不缓存,清空buffer
</span><span class="c1"></span>   <span class="n">response</span><span class="o">.</span><span class="na">setCharacterEncoding</span><span class="o">(</span><span class="s">&#34;UTF-8&#34;</span><span class="o">);</span> <span class="c1">//字符编码
</span><span class="c1"></span>   <span class="n">response</span><span class="o">.</span><span class="na">setContentType</span><span class="o">(</span><span class="s">&#34;multipart/form-data&#34;</span><span class="o">);</span> <span class="c1">//二进制传输数据
</span><span class="c1"></span>   <span class="c1">//设置响应头
</span><span class="c1"></span>   <span class="n">response</span><span class="o">.</span><span class="na">setHeader</span><span class="o">(</span><span class="s">&#34;Content-Disposition&#34;</span><span class="o">,</span>
           <span class="s">&#34;attachment;fileName=&#34;</span><span class="o">+</span><span class="n">URLEncoder</span><span class="o">.</span><span class="na">encode</span><span class="o">(</span><span class="n">fileName</span><span class="o">,</span> <span class="s">&#34;UTF-8&#34;</span><span class="o">));</span>

   <span class="n">File</span> <span class="n">file</span> <span class="o">=</span> <span class="k">new</span> <span class="n">File</span><span class="o">(</span><span class="n">path</span><span class="o">,</span><span class="n">fileName</span><span class="o">);</span>
   <span class="c1">//2、 读取文件--输入流
</span><span class="c1"></span>   <span class="n">InputStream</span> <span class="n">input</span><span class="o">=</span><span class="k">new</span> <span class="n">FileInputStream</span><span class="o">(</span><span class="n">file</span><span class="o">);</span>
   <span class="c1">//3、 写出文件--输出流
</span><span class="c1"></span>   <span class="n">OutputStream</span> <span class="n">out</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="na">getOutputStream</span><span class="o">();</span>

   <span class="kt">byte</span><span class="o">[]</span> <span class="n">buff</span> <span class="o">=</span><span class="k">new</span> <span class="kt">byte</span><span class="o">[</span><span class="n">1024</span><span class="o">];</span>
   <span class="kt">int</span> <span class="n">index</span><span class="o">=</span><span class="n">0</span><span class="o">;</span>
   <span class="c1">//4、执行 写出操作
</span><span class="c1"></span>   <span class="k">while</span><span class="o">((</span><span class="n">index</span><span class="o">=</span> <span class="n">input</span><span class="o">.</span><span class="na">read</span><span class="o">(</span><span class="n">buff</span><span class="o">))!=</span> <span class="o">-</span><span class="n">1</span><span class="o">){</span>
       <span class="n">out</span><span class="o">.</span><span class="na">write</span><span class="o">(</span><span class="n">buff</span><span class="o">,</span> <span class="n">0</span><span class="o">,</span> <span class="n">index</span><span class="o">);</span>
       <span class="n">out</span><span class="o">.</span><span class="na">flush</span><span class="o">();</span>
  <span class="o">}</span>
   <span class="n">out</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
   <span class="n">input</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
   <span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div><p>或者直接用a标签</p>
<p><code>&lt;a href=&quot;/1.jpg&quot;&gt;点击下载&lt;/a&gt;</code></p>

</section>


    <footer class="article-footer">
    
    <section class="article-tags">
        
            <a href="/tags/java/">Java</a>
        
            <a href="/tags/spring/">Spring</a>
        
            <a href="/tags/%E7%AC%94%E8%AE%B0/">笔记</a>
        
    </section>


    
    <section class="article-copyright">
        <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-copyright" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="12" cy="12" r="9" />
  <path d="M14.5 9a3.5 4 0 1 0 0 6" />
</svg>



        <span>Licensed under CC BY-NC-SA 4.0</span>
    </section>
    <section class="article-time">
        <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-clock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="12" cy="12" r="9" />
  <polyline points="12 7 12 12 15 15" />
</svg>



        <span class="article-time--modified">
            最后更新于 Aug 18, 2021 16:00 &#43;0800
        </span>
    </section></footer>


    
</article>

    <aside class="related-contents--wrapper">
    
    
        <h2 class="section-title">相关文章</h2>
        <div class="related-contents">
            <div class="flex article-list--tile">
                
                    
<article class="has-image">
    <a href="/p/spring/">
        
        
            <div class="article-image">
                <img src="/p/spring/82968220.2816b8235b9dc1da1c587b9898b84180_hud03476ee92894581471a20b3a26a7972_2325845_250x150_fill_q75_box_smart1.jpg" 
                        width="250" 
                        height="150" 
                        loading="lazy" 
                        data-key="spring" 
                        data-hash="md5-KBa4I1udwdocWHuYmLhBgA==">
                
            </div>
        

        <div class="article-details">
            <h2 class="article-title">Spring学习笔记</h2>
        </div>
    </a>
</article>
                
                    
<article class="has-image">
    <a href="/p/mybatis/">
        
        
            <div class="article-image">
                <img src="/p/mybatis/86164137.7fe5d91129e0bfd3d085719a1dc82e04_hudf396ad5f75caaaed9aa8bcb008fce93_362314_250x150_fill_q75_box_smart1.jpg" 
                        width="250" 
                        height="150" 
                        loading="lazy" 
                        data-key="mybatis" 
                        data-hash="md5-f&#43;XZESngv9PQhXGaHcguBA==">
                
            </div>
        

        <div class="article-details">
            <h2 class="article-title">MyBatis学习笔记</h2>
        </div>
    </a>
</article>
                
            </div>
        </div>
    
</aside>

     
     
        
    

    <footer class="site-footer">
    <section class="copyright">
        &copy; 
        
            2020 - 
        
        2021 luoboQAQ
    </section>
    
    <section class="powerby">
        Built with <a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a> <br />
        Theme <b><a href="https://github.com/CaiJimmy/hugo-theme-stack" target="_blank" rel="noopener" data-version="3.0.0">Stack</a></b> designed by <a href="https://jimmycai.com" target="_blank" rel="noopener">Jimmy</a>
    </section>
</footer>

    
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    
    <div class="pswp__bg"></div>

    
    <div class="pswp__scroll-wrap">

        
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                
                
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div><script 
                src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"integrity="sha256-ePwmChbbvXbsO02lbM3HoHbSHTHFAeChekF1xKJdleo="crossorigin="anonymous"
                defer="true"
                >
            </script><script 
                src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"integrity="sha256-UKkzOn/w1mBxRmLLGrSeyB4e1xbrp4xylgAWb3M42pU="crossorigin="anonymous"
                defer="true"
                >
            </script><link 
                rel="stylesheet" 
                href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.css"integrity="sha256-c0uckgykQ9v5k&#43;IqViZOZKc47Jn7KQil4/MP3ySA3F8="crossorigin="anonymous"
            ><link 
                rel="stylesheet" 
                href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.css"integrity="sha256-SBLU4vv6CA6lHsZ1XyTdhyjJxCjPif/TRkjnsyGAGnE="crossorigin="anonymous"
            >

            </main>
    
        <aside class="sidebar right-sidebar sticky">
            <section class="widget archives">
                <div class="widget-icon">
                    <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-hash" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <line x1="5" y1="9" x2="19" y2="9" />
  <line x1="5" y1="15" x2="19" y2="15" />
  <line x1="11" y1="4" x2="7" y2="20" />
  <line x1="17" y1="4" x2="13" y2="20" />
</svg>



                </div>
                <h2 class="widget-title section-title">目录</h2>
                
                <div class="widget--toc">
                    <nav id="TableOfContents">
  <ol>
    <li><a href="#回顾mvc">回顾MVC</a>
      <ol>
        <li><a href="#什么是mvc">什么是MVC</a></li>
        <li><a href="#复习servlet">复习Servlet</a></li>
      </ol>
    </li>
    <li><a href="#什么是springmvc">什么是SpringMVC</a>
      <ol>
        <li><a href="#概述">概述</a></li>
        <li><a href="#中心控制器">中心控制器</a></li>
        <li><a href="#springmvc执行原理">SpringMVC执行原理</a></li>
      </ol>
    </li>
    <li><a href="#第一个springmvc程序">第一个SpringMVC程序</a>
      <ol>
        <li>
          <ol>
            <li><a href="#配置版">配置版</a></li>
            <li><a href="#注解版">注解版</a></li>
            <li><a href="#小结">小结</a></li>
          </ol>
        </li>
      </ol>
    </li>
    <li><a href="#restful风格">RestFul风格</a></li>
    <li><a href="#重定向和转发">重定向和转发</a></li>
    <li><a href="#数据处理">数据处理</a>
      <ol>
        <li><a href="#处理提交数据">处理提交数据</a></li>
        <li><a href="#数据显示到前端">数据显示到前端</a></li>
        <li><a href="#对比">对比</a>
          <ol>
            <li><a href="#解决乱码">解决乱码</a></li>
          </ol>
        </li>
      </ol>
    </li>
    <li><a href="#json">JSON</a>
      <ol>
        <li><a href="#使用jackson">使用Jackson</a></li>
        <li><a href="#使用fastjson">使用FastJson</a></li>
      </ol>
    </li>
    <li><a href="#拦截器">拦截器</a>
      <ol>
        <li><a href="#概述-1">概述</a></li>
        <li><a href="#使用方法">使用方法</a></li>
      </ol>
    </li>
    <li><a href="#文件传输">文件传输</a>
      <ol>
        <li><a href="#文件上传">文件上传</a></li>
        <li><a href="#文件下载">文件下载</a></li>
      </ol>
    </li>
  </ol>
</nav>
                </div>
            </section>
        </aside>
    

        </div>
        <script 
                src="https://cdn.jsdelivr.net/npm/node-vibrant@3.1.5/dist/vibrant.min.js"integrity="sha256-5NovOZc4iwiAWTYIFiIM7DxKUXKWvpVEuMEPLzcm5/g="crossorigin="anonymous"
                defer="false"
                >
            </script><script type="text/javascript" src="/ts/main.js" defer></script>
<script>
    (function () {
        const customFont = document.createElement('link');
        customFont.href = "https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&display=swap";

        customFont.type = "text/css";
        customFont.rel = "stylesheet";

        document.head.appendChild(customFont);
    }());
</script>

    </body>
</html>
